如何使用PyInstaller打包Python代碼為執行檔

您所在的位置:网站首页 python tkinter exe 如何使用PyInstaller打包Python代碼為執行檔

如何使用PyInstaller打包Python代碼為執行檔

2024-07-09 16:16| 来源: 网络整理| 查看: 265

上週五好不容易用Python內建的Tkinter將操作介面拉好且測試OK,沒想到在打包成執行檔(.exe)這邊花了一個上午,所以紀錄一下自己的碰壁流程。

工作環境:-Windows 10, Windows Server 2019-Anaconda 2020.02-Python 3.6.10

問題描述:

如何用PyInstaller打包Python代碼為執行檔(.exe) 打包過程碰上的問題以及如何排除 先安裝PyInstaller: pip install pyinstaller 打開Anaconda Prompt (anaconda3),並且將當前位置切至.py檔存放路徑: cd C:\Users\*\Documents\GUI-20200323 輸入打包代碼,我要打包的是main.py。一般的教程都只到這邊就停了,但後面才蛋疼: pyinstaller main.py 4. 問題:RecursionError: maximum recursion depth exceeded File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 253, in visit return visitor(node) File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 263, in generic_visit self.visit(value) File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 253, in visit return visitor(node) File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 263, in generic_visit self.visit(value) File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 253, in visit return visitor(node) File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 263, in generic_visit self.visit(value) File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 253, in visit return visitor(node) File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 257, in generic_visit for field, value in iter_fields(node): RecursionError: maximum recursion depth exceeded

突然蹦出這些有的沒的,解決方法很簡單,看一下.py檔存放路徑是不是出現了main.spec這個由PyInstaller自動產生的配置文件,用筆記本打開後新增下面兩行代碼後儲存離開,然後保險起見將build和dist兩個資料夾刪除:原因在於超過遞迴限制,我也看不懂這什麼意思。[8]

# -*- mode: python ; coding: utf-8 -*- import sys #我是新增的 sys.setrecursionlimit(9000000) #我是新增的,這邊數字越大越好 block_cipher = None a = Analysis(['main.py'], pathex=['C:\\Users\\*\\Documents\\GUI-20200323'], binaries=[], datas=[], hiddenimports=[], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) 執行配置文件main.spec進行打包解決上個問題後我們輸入下列代碼來重新製作執行檔,這次我們是要執行自訂的配置文件.spec,PyInstaller會遵循.spec指定規範進行打包: pyinstaller main.spec 6-1. 閃退問題以及如何查詢原因(pkg_resources.py2_warn)

等了一會兒後終於跑完了:

113390 INFO: checking EXE 113390 INFO: Building EXE because EXE-00.toc is non existent 113391 INFO: Building EXE from EXE-00.toc 113391 INFO: Appending archive to EXE C:\Users\*\Documents\GUI-20200323\build\main\main.exe 113486 INFO: Building EXE from EXE-00.toc completed successfully. 113501 INFO: checking COLLECT 113502 INFO: Building COLLECT because COLLECT-00.toc is non existent 113502 INFO: Building COLLECT COLLECT-00.toc 184733 INFO: Building COLLECT COLLECT-00.toc completed successfully.

我們來看看main.exe是不是可以正常地打開吧,main.exe的位置在:

C:\Users\*\Documents\GUI-20200323\dist\main\main.exe

但是等等,為什麼會閃退!!!原來打包成功並不等於.exe可以順利執行呀。既然這樣那我們改用終端機來開啟.exe,這樣就能知道程是閃退的原因了[1]:

(keras4) C:\Users\*\Documents\GUI-20200323>cd C:\Users\*\Documents\GUI-20200323\dist\main #切換路徑到main.exe的位置 (keras4) C:\Users\*\Documents\GUI-20200323\dist\main>main.exe #執行 Traceback (most recent call last): File "site-packages\PyInstaller\loader\rthooks\pyi_rth_pkgres.py", line 13, in File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 623, in exec_module exec(bytecode, module.__dict__) File "site-packages\pkg_resources\__init__.py", line 86, in ModuleNotFoundError: No module named 'pkg_resources.py2_warn'# 這個是問題來源 [15208] Failed to execute script pyi_rth_pkgres (keras4) C:\Users\*\Documents\GUI-20200323\dist\main>

原來是因為PyInstaller再打包過程中漏掉pkg_resources.py2_warn導致產生的.exe無法順利執行。這時我們再次開啟配置文件.spec,手動添加pkg_resources.py2_warn吧,記得再次執行main.spec前要先刪掉build、dist兩個資料夾[2][3][4]:

# -*- mode: python ; coding: utf-8 -*- import sys sys.setrecursionlimit(9000000) block_cipher = None a = Analysis(['main.py'], pathex=['C:\\Users\\*\\Documents\\GUI-20200323'], binaries=[], datas=[], hiddenimports=['pkg_resources.py2_warn'], #我是新增的 hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) pyinstaller main.spec 6-2. 閃退問題以及如何查詢原因(sklearn.utils._cython_blas)

現在我們再次執行.exe,結果又閃退了...,沒關係我們用上面講的方法,透過終端機來執行.exe檔就能知道問題了:

(keras4) C:\Users\*\Documents\GUI-20200323>cd C:\Users\*\Documents\GUI-20200323\dist\main #切換路徑到main.exe的位置 (keras4) C:\Users\*\Documents\GUI-20200323\dist\main>main.exe # 執行 Traceback (most recent call last): File "main.py", line 3, in File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 623, in exec_module exec(bytecode, module.__dict__) File "mylib.py", line 10, in File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 623, in exec_module exec(bytecode, module.__dict__) File "site-packages\sklearn\linear_model\__init__.py", line 12, in File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 623, in exec_module exec(bytecode, module.__dict__) File "site-packages\sklearn\linear_model\_least_angle.py", line 22, in File "sklearn\utils\arrayfuncs.pyx", line 1, in init sklearn.utils.arrayfuncs ModuleNotFoundError: No module named 'sklearn.utils._cython_blas'# 這個是問題來源 [11656] Failed to execute script main (keras4) C:\Users\*\Documents\GUI-20200323\dist\main>

這次是打包過程中漏掉sklearn.utils._cython_blas,PyInstaller你這個小淘氣~:

# -*- mode: python ; coding: utf-8 -*- import sys sys.setrecursionlimit(9000000) block_cipher = None a = Analysis(['main.py'], pathex=['C:\\Users\\*\\Documents\\GUI-20200323'], binaries=[], datas=[], hiddenimports=['pkg_resources.py2_warn', 'sklearn.utils._cython_blas'], # 再加1個 hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) 收工根據孟母三遷原理,我們終於順利打包完成並且可以執行main.exe了(灑花)。然後你的螢幕會彈出辛苦拉的視窗以及一個黑色畫面,消除黑色畫面的方法很簡單,只要依照下面代碼位置方式修改.spec檔後再次打包即可。成果 a = Analysis(['main.py'], pathex=['C:\\Users\\*\\Documents\\GUI-20200323'], binaries=[], datas=[], hiddenimports=['pkg_resources.py2_warn', 'sklearn.utils._cython_blas'], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, [], exclude_binaries=True, name='main', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, console=False # console要從True改成False)

結論:

打包完成不等於可以順利運行.exe檔 PyInstaller的打包方式是由.spec定義 我們可以自定義.spec 如果有引用第三方套件(Numpy、Pandas等等),容易有漏打包問題,導致執行檔有閃退問題 用終端機執行.exe來確認閃退原因 每次自動打包前都要刪掉資料夾build、資料夾dist、配置文件.spec,以確保遺毒消除 每次手動打包前都要刪掉資料夾build、資料夾dist,以確保遺毒消除 補一下最後的main.spec代碼,可以拿來跟下一篇比較 # -*- mode: python ; coding: utf-8 -*- import sys # 這邊要注意 sys.setrecursionlimit(9000000) # 這邊要注意 block_cipher = None a = Analysis(['main.py'], pathex=['C:\\Users\\e10832\\Documents\\GUI-20200323'], binaries=[], datas=[], hiddenimports=['pkg_resources.py2_warn', 'sklearn.utils._cython_blas'], # 這邊要注意 hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, [], exclude_binaries=True, name='main', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, console=True )# 命令視窗開啟(True) coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, upx_exclude=[], name='main')

參考資料:[1]https://blog.csdn.net/weixin_41417982/article/details/82216363[2]https://blog.csdn.net/qq_40587575/article/details/86500445[3]https://blog.csdn.net/j754379117/article/details/77281354[4]https://medium.com/@peaceful0907/%E5%B0%87%E4%BD%A0%E7%9A%84python-code-%E6%89%93%E5%8C%85-pyinstaller-6777d0e06f58[5]https://zhuanlan.zhihu.com/p/58199926[6]https://zhuanlan.zhihu.com/p/40716095[7]https://zhuanlan.zhihu.com/p/76974787[8]https://xken831.pixnet.net/blog/post/463075799-%5Bpython%5D-%E8%A7%A3%E6%B1%BA-recursionerror%3A-maximum-recursion-depth-exce



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3